<?php
namespace App\Services\ThirdPayments\Recharge;

use App\Lib\PaymentMap;
use App\Lib\ThirdPartyMap;
use App\Models\RechargeOrder;
use App\Services\ThirdPayments\BankTraits\HCADBankMap;
use App\Services\ThirdPayments\Contracts\Actions\HrefRedirectAction;
use App\Services\ThirdPayments\Contracts\RechargeBaseAbstract;
use App\Services\ThirdPayments\Contracts\WAPable;

class HCADPayment extends RechargeBaseAbstract implements WAPable
{
    use HCADBankMap;

    protected $gw_pay = 'http://api.hc-ad.cn/pay.aspx';
    protected $gw_query = 'http://api.hc-ad.cn/query.aspx';

    public function callback(array $data)
    {
        // TODO: Implement callback() method.
        if ($this->veryCallbackSign($data) && $this->veryCallbackSign2($data)) {
            if ($data['returncode'] == '1') return true;
        }
        return false;
    }

    public function veryCallbackSign(array $data)
    {
        // TODO: Implement veryCallbackSign() method.
        $signStr = "returncode={$data['returncode']}&userid={$data['userid']}&orderid={$data['orderid']}&keyvalue={$this->getMchKey()}";
        if ($data['sign'] == md5($signStr)) {
            return true;
        }
        return false;
    }

    public function getOrderNoFromCallback(array $data)
    {
        // TODO: Implement getOrderNoFromCallback() method.
        return $data['orderid'];
    }

    public function getOrderAmtFromCallback(array $data)
    {
        // TODO: Implement getOrderAmtFromCallback() method.
        return $data['money'];
    }

    /**
     * @return mixed
     */
    public function getIdentify(): string
    {
        // TODO: Implement getIdentify() method.
        return ThirdPartyMap::HCAD;
    }

    /**
     *  needs child to achieve
     */
    public function initPaymentMap(): array
    {
        // TODO: Implement initPaymentMap() method.
        return [
            PaymentMap::WX => '2001',
            PaymentMap::ALI => '2003',
            PaymentMap::WX_WAP => '2005',
            PaymentMap::ALI_WAP => '2007',
            PaymentMap::QQ => '2008',
            PaymentMap::QQ_WAP => '2009',
            PaymentMap::BANK_WAP => '2012',
            PaymentMap::BANK_SCAN => '2012'
        ];
    }

    public function query(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement query() method.
        $this->setParameter('userid', $this->getMchId());
        $this->setParameter('orderid', $rechargeOrder->plat_no);
        $this->setParameter('sign', $this->querySign());

        try {
            $res = curlHttp($this->getGwQuery(), $this->getParameters(), 'get');
            if ($res['http_code'] == 200) {
                //returncode={}&orderid={}&paymoney={}&sign={}
                parse_str($res['body'],$res_arr);
                $signPar = "returncode={$res_arr['returncode']}&orderid={$res_arr['orderid']}&paymoney={$res_arr['paymoney']}&keyvalue={$this->getMchKey()}";
                if (md5($signPar) == $res_arr['sign'] && $res_arr['paymoney'] == $rechargeOrder->order_amt && $res_arr['returncode'] == 1) {
                    return true;
                }
            }
            return $res['body'];
        } catch (\Exception $exception) {
            return $exception->getMessage();
        }
    }

    public function bankHref(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement bankHref() method.
        $this->initParameters($rechargeOrder);
        return $this->getGwPay() . '?' . http_build_query($this->getParameters());
    }

    public function scanCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement scanCode() method.
        $this->initParameters($rechargeOrder);
        return $this->getGwPay() . '?' . http_build_query($this->getParameters());
    }

    public function paySign(): string
    {
        // TODO: Implement paySign() method.
        $sign = "userid={$this->getParameter('userid')}";
        $sign .= "&orderid={$this->getParameter('orderid')}";
        $sign .= "&bankid={$this->getParameter('bankid')}";
        $sign .= "&keyvalue={$this->getMchKey()}";
        return md5($sign);
    }

    public function querySign(): string
    {
        // TODO: Implement querySign() method.
        $sign = "userid={$this->getParameter('userid')}&orderid={$this->getParameter('orderid')}&keyvalue={$this->getMchKey()}";
        return md5($sign);
    }

    public function showSuccess(): string
    {
        // TODO: Implement showSuccess() method.
        return "ok";
    }

    public function initParameters(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement initParameters() method.
        $this->setParameter('userid', $this->getMchId());
        $this->setParameter('orderid', $rechargeOrder->plat_no);
        $this->setParameter('money', $rechargeOrder->order_amt);
        $this->setParameter('url', $this->getCallbackUrl());
        $this->setParameter('aurl', $this->getReturnUrl());
        $this->setParameter('bankid', $this->getBankId($rechargeOrder));
        $this->setParameter('sign', $this->paySign());
        $this->setParameter('ext', $this->setRemark($rechargeOrder));
        $this->setParameter('sign2', $this->paySign2());
    }

    public function getBankId(RechargeOrder $rechargeOrder)
    {
        $mchData = $rechargeOrder->order_data;
        if ($mchData['recharge_type'] == PaymentMap::BANK) {
            return $this->getBank($mchData['bank_code']);
        } else {
            return $this->getPaymentMap($mchData['recharge_type']);
        }
    }

    public function paySign2()
    {
        $sign = "money={$this->getParameter('money')}&userid={$this->getParameter('userid')}&orderid={$this->getParameter('orderid')}&bankid={$this->getParameter('bankid')}&keyvalue={$this->getMchKey()}";
        return md5($sign);

    }

    public function veryCallbackSign2($data)
    {
        $signStr = "money={$data['money']}&returncode={$data['returncode']}&userid={$data['userid']}&orderid={$data['orderid']}&keyvalue={$this->getMchKey()}";
        if ($data['sign2'] == md5($signStr)) {
            return true;
        }
        return false;
    }

    public function wapReq(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement wapReq() method.
        $this->initParameters($rechargeOrder);
        $url = $this->getGwPay() . '?' . http_build_query($this->getParameters());
        return new HrefRedirectAction($url);
    }
}
